#include"riscv.h"
// #include"parama.h"
// #include"defs.h"

void main();

__attribute__ ((aligned (16))) char stack0[4096];

void start() {
    // 读取 mstatus 并修改 MPP 字段，让 CPU 进入 S-mode
    unsigned long x = r_mstatus();
    x &= ~MSTATUS_MPP_MASK;  // 清除 MPP 位
    x |= MSTATUS_MPP_S;      // 设置 MPP 为 S-mode，置为00
    w_mstatus(x);            // 写回 machine_mode_status

    // 设置 mret 的返回地址为 `main()`
    //mechine_mode的返回地址
    //这样你下文的mret就会来到你的main的地址啦
    w_mepc((uint64)main);

    // 关闭分页（使用物理地址）
    //将0写入satp寄存器
    w_satp(0);

    // 将所有异常和中断委托给 S-mode
    w_medeleg(0xffff);
    w_mideleg(0xffff);
    w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);

    // 允许 S-mode 访问所有物理内存
    w_pmpaddr0(0x3fffffffffffffull);
    w_pmpcfg0(0xf);

    // 设置定时器
    //w_mie(r_mie() | MIE_STIE); // 允许 S-mode 处理时钟中断
    //w_stimecmp(r_time() + 1000000); // 设置下次时钟中断

    // 记录 CPU ID
    int id = r_mhartid();
    //写入tp寄存器，存储当前CPU状态
    w_tp(id);

    // 切换到 S-mode 并进入 `main()`
    asm volatile("mret");
}